#set( $symbol_pound = '#' )
#set( $symbol_dollar = '$' )
#set( $symbol_escape = '\' )
/*
 * Copyright © 2014, Finium Sdn Bhd, All Rights Reserved
 * 
 * RedisTemplateAspect.java
 * Modification History
 * *************************************************************
 * Date				Author			Comment
 * Nov 6, 2013			Alvin Leong Chee Foo			Created
 * *************************************************************
 */
package ${package}.test;

import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.stereotype.Component;

/**
 * @author Alvin Leong Chee Foo
 * 
 */
@Component
@Aspect
public class RedisRepositoryAspect
{
    private static final Log LOG = LogFactory
            .getLog(RedisRepositoryAspect.class);

    @Autowired
    private MessageSource messageSource;

    /**
     * Pointcut for <code>Set List</code> annotation
     */
    @Pointcut("execution(* ${package}.redis.dao.RedisRepository.setList(..)) && args(key, value)")
    public void setListPointcut(String key, byte[] value)
    {

    }

    /**
     * Pointcut for <code>Get List</code> annotation
     */
    @Pointcut("execution(* ${package}.redis.dao.RedisRepository.getList(..)) && args(key)")
    public void getListPointcut(String key)
    {

    }

    /**
     * 
     * @param joinPoint
     * @param key
     * @return
     * @throws Throwable
     */
    @Around("setListPointcut(key, value)")
    public void processSetListRequest(ProceedingJoinPoint joinPoint,
            String key, byte[] value) throws Throwable
    {
        LOG.debug("Set List Point Cut Intercept");
    }

    /**
     * 
     * @param joinPoint
     * @param key
     * @return
     * @throws Throwable
     */
    @Around("getListPointcut(key)")
    public List<byte[]> processGetListRequest(ProceedingJoinPoint joinPoint,
            String key) throws Throwable
    {
        LOG.debug("Get List Point Cut Intercept");

        return ThreadLocalRedis.getList();
    }

    /**
     * Pointcut for <code>Set List</code> annotation
     */
    @Pointcut("execution(* ${package}.redis.dao.RedisRepository.setValue(..)) && args(key, value)")
    public void setPointcut(String key, byte[] value)
    {

    }

    /**
     * Pointcut for <code>Get List</code> annotation
     */
    @Pointcut("execution(* ${package}.redis.dao.RedisRepository.getValue(..)) && args(key)")
    public void getPointcut(String key)
    {

    }

    /**
     * 
     * @param joinPoint
     * @param key
     * @return
     * @throws Throwable
     */
    @Around("setPointcut(key, value)")
    public void processSetRequest(ProceedingJoinPoint joinPoint, String key,
            byte[] value) throws Throwable
    {
        LOG.debug("Set Bytes Point Cut Intercept");

        ThreadLocalRedis.setBytes(value);
    }

    /**
     * 
     * @param joinPoint
     * @param key
     * @return
     * @throws Throwable
     */
    @Around("getPointcut(key)")
    public byte[] processGetRequest(ProceedingJoinPoint joinPoint, String key)
            throws Throwable
    {
        LOG.debug("Get Bytes Point Cut Intercept");
        return ThreadLocalRedis.getBytes();
    }

    /**
     * Pointcut for <code>Set List</code> annotation
     */
    @Pointcut("execution(* ${package}.redis.dao.RedisRepository.setStrValue(..)) && args(key, value)")
    public void setStrPointcut(String key, String value)
    {

    }

    /**
     * Pointcut for <code>Get List</code> annotation
     */
    @Pointcut("execution(* ${package}.redis.dao.RedisRepository.getStrValue(..)) && args(key)")
    public void getStrPointcut(String key)
    {

    }

    /**
     * 
     * @param joinPoint
     * @param key
     * @return
     * @throws Throwable
     */
    @Around("setStrPointcut(key, value)")
    public void processSetStrRequest(ProceedingJoinPoint joinPoint, String key,
            String value) throws Throwable
    {
        LOG.debug("Set String Point Cut Intercept");

        ThreadLocalRedis.setBytes(value.getBytes());
    }

    /**
     * 
     * @param joinPoint
     * @param key
     * @return
     * @throws Throwable
     */
    @Around("getStrPointcut(key)")
    public String processGetStrRequest(ProceedingJoinPoint joinPoint, String key)
            throws Throwable
    {
        LOG.debug("Get String Point Cut Intercept");
        if (ThreadLocalRedis.getBytes() != null)
        {
            return new String(ThreadLocalRedis.getBytes());
        }

        return null;
    }

    /**
     * Pointcut for <code>Set List</code> annotation
     */
    @Pointcut("execution(* ${package}.redis.dao.RedisRepository.hasKey(..)) && args(key)")
    public void hasKeyPointcut(String key)
    {

    }

    /**
     * 
     * @param joinPoint
     * @param key
     * @return
     * @throws Throwable
     */
    @Around("hasKeyPointcut(key)")
    public boolean processHasKeyRequest(ProceedingJoinPoint joinPoint,
            String key) throws Throwable
    {
        LOG.debug("Get List Point Cut Intercept");

        if (ThreadLocalRedis.getBytes() != null)
        {
            return Boolean
                    .parseBoolean(new String(ThreadLocalRedis.getBytes()));
        }

        return false;
    }

    /**
     * Pointcut for <code>SetValue</code> annotation
     */
    @Pointcut("execution(* ${package}.redis.dao.RedisRepository.setValue(..)) && args(key, value, onlyIfAbsent)")
    public void setOnlyIfAbsentPointcut(String key, byte[] value,
            boolean onlyIfAbsent)
    {

    }

    /**
     * default return will be true.
     * 
     * @param joinPoint
     * @param key
     * @return
     * @throws Throwable
     */
    @Around("setOnlyIfAbsentPointcut(key, value, onlyIfAbsent)")
    public boolean processSetRequest(ProceedingJoinPoint joinPoint, String key,
            byte[] value, boolean onlyIfAbsent) throws Throwable
    {
        LOG.debug("Set Bytes (Only If Absent) Point Cut Intercept");

        if (onlyIfAbsent)
        {
            if (ThreadLocalRedis.getBytes() != null)
            {
                return false;
            }

            ThreadLocalRedis.setBytes(value);
            return true;
        }

        ThreadLocalRedis.setBytes(value);
        return true;
    }
}
